use probe_rs::config::MemoryRegion;

use crate::*;

pub fn probe_attach(ui_io: &UiIo) -> Option<Session> {
    let lister = Lister::new();
    let probes = lister.list_all();
    let identifier = ui_io.get_selected_probe().to_string();

    for dbg_probe in probes {
        if identifier == dbg_probe.identifier {
            match dbg_probe.open() {
                Ok(probe) => {
                    let target_core: String = ui_io.get_selected_core().into();
                    match probe.attach(target_core, Permissions::default()) {
                        Ok(mut session) => {
                            let target = session.target().clone();
                            let s = &mut session;
                            let mut core = s.core(0).unwrap();
                            match core.halt(Duration::from_millis(500)) {
                                Ok(cpu_info) => {
                                    for mem_region in target.memory_map {
                                        if let MemoryRegion::Nvm(nvm) = mem_region {
                                            let start = nvm.range.start;
                                            let size = nvm.range.end - start + 1;
                                            ui_io.set_flash_start_address(
                                                format!("0x{:08X}", start).into(),
                                            );
                                            ui_io.set_flash_size(format!("{}", size).into());
                                            update_mcu_core(&mut core, &ui_io, cpu_info.pc);

                                            break;
                                        }
                                    }
                                }
                                Err(e) => {
                                    println!("{:?}", e);
                                }
                            }
                            drop(core);

                            return Some(session);
                        }
                        Err(e) => {
                            ui_io.set_help_tip(format!("probe.attach ERR: {:?}", e).into());
                        }
                    }
                }
                Err(e) => {
                    ui_io.set_help_tip(format!("probe.open ERR: {:?}", e).into());
                }
            }
            break;
        }
    }

    return None;
}

pub fn reflash_probe_list(ui_io: &UiIo) {
    let lister = Lister::new();
    let probes = lister.list_all();
    let mut probe_identifier: Vec<String> = Vec::new();
    for probe in probes {
        //println!("{:?}", probe.identifier);
        probe_identifier.push(probe.identifier);
    }

    let probe_identifier = utils::string_to_shared_string(&probe_identifier);
    if probe_identifier.len() > 0 {
        ui_io.set_selected_probe(probe_identifier[0].clone());
    }
    ui_io.set_probe_list(Rc::new(VecModel::from(probe_identifier)).into());
}
